﻿using System.Collections.Generic;
using Microsoft.Practices.ServiceLocation;
using Mockery.Core;
using NUnit.Framework;
using Rhino.Mocks;

namespace Mockery.UnitTest
{
    [TestFixture]
    public class MockeryIntegrationTests
    {
        [Test]
        public void Mockery_FullIntegration()
        {
            var testResult = -1;

            InjectedTest.Target<Foo>()
                .Arrange(c => c.AddStrictMock<IFooDependency>()
                               .ExpectOn<IFooDependency>(m => Expect.Call(m.Go(1, 2)).Return(3)))
                .Act(m => testResult = m.Go(1, 2))
                .Assert(() => Assert.That(testResult, Is.EqualTo(6)));
        }

        [Test]
        public void Mockery_MissingDependency()
        {
            var testResult = 0;

            Assert.That(
                Assert.Throws<UnexpectedException>(() =>
                                                   InjectedTest.Target<Foo>()
                                                       .Arrange(
                                                       a => a.AddSingletonType(new MockeryIntegrationTests()))
                                                       .Act(m => testResult = m.Go(1, 2))
                                                       .Assert(() => Assert.That(testResult, Is.EqualTo(6)))).
                    InnerException, Is.TypeOf(typeof(ActivationException)));

        }


        [Test]
        public void Mockery_ArrangementLookupInError()
        {
            var testResult = 0;

            Assert.That(
                Assert.Throws<MissingMockException>(() =>
                                                   InjectedTest.Target<Foo>()
                                                       .Arrange(
                                                       a => a.AddSingletonType(new MockeryIntegrationTests())
                                                             .ExpectOn<IFooDependency>(e =>Expect.Call(e.Go(2,4)).Return(6)))
                                                       .Act(m => testResult = m.Go(1, 2))
                                                       .Assert(() => Assert.That(testResult, Is.EqualTo(6)))).
                    InnerException, Is.TypeOf(typeof (KeyNotFoundException)));
        }
    }

    #region Supporting Test Code

    public interface IFooDependency
    {
        int Go(int a, int b);
    }

    public class Foo
    {
        private readonly IFooDependency _fooDependency;

        public Foo(IFooDependency fooDependency)
        {
            _fooDependency = fooDependency;
        }

        public int Go(int a, int b)
        {
            return _fooDependency.Go(a, b)*2;
        }
    }

    #endregion
}
